﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Threading;

namespace SyncChatServer
{
    public partial class Form1 : Form
    {
        private List<User> userList = new List<User>();
        IPAddress localAddress;
        private int port = 51888;
        private TcpListener myListener;
        bool isNormalExit = false;
        public Form1()
        {
            InitializeComponent();
            listBox1.HorizontalScrollbar = true;
            string myHostName = Dns.GetHostName();
            IPAddress[] addrIP = Dns.GetHostAddresses(myHostName);
            localAddress = addrIP[5];
            buttonStop.Enabled = false;
        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            myListener = new TcpListener(localAddress, port);
            myListener.Start();
            listBox1.Items.Add(string.Format("开始在{0}:{1}侦听客户连接", localAddress, port));
            Thread myThread = new Thread(ListenClientConnect);
            myThread.Start();
            buttonStart.Enabled = false;
            buttonStop.Enabled = true;
        }

        private void ListenClientConnect(object obj)
        {
            TcpClient newClient = null;
            while (true)
            {
                try
                {
                    newClient = myListener.AcceptTcpClient();
                }
                catch (Exception)
                {
                    break;
                }
                User user = new User(newClient);
                Thread threadReceive = new Thread(ReceiveData);
                threadReceive.Start(user);
                userList.Add(user);
                AddItemToListBox(string.Format("[{0}],进入", newClient.Client.RemoteEndPoint));
                AddItemToListBox(string.Format("当前用户连接数：{0}", userList.Count));
            }
        }
        private delegate void AddItemToListBoxDelegate(string str);
        private void AddItemToListBox(string p)
        {
            if (listBox1.InvokeRequired)
            {
                AddItemToListBoxDelegate d = AddItemToListBox;
                listBox1.Invoke(d, p);
            }
            else
            {
                listBox1.Items.Add(p);
                listBox1.SelectedIndex = listBox1.Items.Count - 1;
                listBox1.ClearSelected();
            }
        }

        private void ReceiveData(object userState)
        {
            User user = (User)userState;
            while (isNormalExit == false)
            {
                string receiveString = null;
                try
                {
                    receiveString = user.br.ReadString();
                }
                catch
                {

                    if (isNormalExit == false)
                    {
                        listBox1.Items.Add(string.Format("与[{0}]失去连接，已终止接受该用户信息。"));
                        RemoveUser(user);
                    }
                    break;
                }
                AddItemToListBox(string.Format("来自[{0}:{1}]", user.tcpClient.Client.RemoteEndPoint, receiveString));
                string[] splitString = receiveString.Split(',');
                switch (splitString[0])
                {
                    case "Login":
                        user.userName = splitString[1];
                        SendToAllClent(user, receiveString);
                        break;
                    case "Logout":
                        SendToAllClent(user, receiveString);
                        RemoveUser(user);
                        break;
                    case "Talk":
                        string talkString = receiveString.Substring(splitString[0].Length + splitString[1].Length + 2);
                        AddItemToListBox(string.Format("{0}对{1}说：{2}", user.tcpClient.Client.RemoteEndPoint, splitString[1], talkString));
                        SendToClient(user, "talk," + user.userName + "," + talkString);
                        foreach (User item in userList)
                        {
                            if (item.userName == splitString[1] && user.userName != splitString[1])
                            {
                                SendToClient(item, "talk," + user.userName + "," + talkString);
                                break;
                            }
                        }
                        break;
                    default:
                        AddItemToListBox(string.Format("什么意思啊： " + receiveString));
                        break;
                }
            }
        }

        private void SendToClient(User user, string message)
        {
            try
            {
                user.bw.Write(message);
                user.bw.Flush();
                AddItemToListBox(string.Format("向[{0}]发送：{1}", user.userName, message));
            }
            catch (Exception)
            {
                AddItemToListBox(string.Format("向[{0}]发送失败", user.userName));
            }
        }

        private void SendToAllClent(User user, string message)
        {
            string command = message.Split(',')[0].ToLower();
            if (command == "login")
            {
                for (int i = 0; i < userList.Count; i++)
                {
                    SendToClient(userList[i], message);
                    if (userList[i].userName != user.userName)
                    {
                        SendToClient(user, "login," + userList[i].userName);
                    }
                }
            }
            else if (command == "logout")
            {
                for (int i = 0; i < userList.Count; i++)
                {
                    if (userList[i].userName != user.userName)
                    {
                        SendToClient(userList[i], message);
                    }
                }
            }
        }

        private void RemoveUser(User user)
        {
            userList.Remove(user);
            user.Close();
            AddItemToListBox(string.Format("当前用户连接数：{0}", userList.Count));
        }

        private void buttonStop_Click(object sender, EventArgs e)
        {
            AddItemToListBox("开始停止服务，并依次使用户退出!  ");
            isNormalExit = true;
            for (int i = userList.Count-1; i >= 0; i--)
            {
                RemoveUser(userList[i]);
            }
            myListener.Stop();
            buttonStart.Enabled = true;
            buttonStop.Enabled = false;
        }
    }
}
